package javax.vecmath;

import org.lwjgl.util.vector.Vector4f;

import java.nio.FloatBuffer;

public class Matrix4f {
    public float m00, m01, m02, m03;
    public float m10, m11, m12, m13;
    public float m20, m21, m22, m23;
    public float m30, m31, m32, m33;
    
    public Matrix4f() {
        setIdentity();
    }
    
    public Matrix4f(org.lwjgl.util.vector.Matrix4f matrix) {
        set(matrix);
    }
    
    public final void set(org.lwjgl.util.vector.Matrix4f matrix) {
        m00 = matrix.m00; m01 = matrix.m01; m02 = matrix.m02; m03 = matrix.m03;
        m10 = matrix.m10; m11 = matrix.m11; m12 = matrix.m12; m13 = matrix.m13;
        m20 = matrix.m20; m21 = matrix.m21; m22 = matrix.m22; m23 = matrix.m23;
        m30 = matrix.m30; m31 = matrix.m31; m32 = matrix.m32; m33 = matrix.m33;
    }
    
    public final void setIdentity() {
        m00 = 1.0f; m01 = 0.0f; m02 = 0.0f; m03 = 0.0f;
        m10 = 0.0f; m11 = 1.0f; m12 = 0.0f; m13 = 0.0f;
        m20 = 0.0f; m21 = 0.0f; m22 = 1.0f; m23 = 0.0f;
        m30 = 0.0f; m31 = 0.0f; m32 = 0.0f; m33 = 1.0f;
    }
    
    public final void mul(Matrix4f m1) {
        float t00 = m00 * m1.m00 + m01 * m1.m10 + m02 * m1.m20 + m03 * m1.m30;
        float t01 = m00 * m1.m01 + m01 * m1.m11 + m02 * m1.m21 + m03 * m1.m31;
        float t02 = m00 * m1.m02 + m01 * m1.m12 + m02 * m1.m22 + m03 * m1.m32;
        float t03 = m00 * m1.m03 + m01 * m1.m13 + m02 * m1.m23 + m03 * m1.m33;
        float t10 = m10 * m1.m00 + m11 * m1.m10 + m12 * m1.m20 + m13 * m1.m30;
        float t11 = m10 * m1.m01 + m11 * m1.m11 + m12 * m1.m21 + m13 * m1.m31;
        float t12 = m10 * m1.m02 + m11 * m1.m12 + m12 * m1.m22 + m13 * m1.m32;
        float t13 = m10 * m1.m03 + m11 * m1.m13 + m12 * m1.m23 + m13 * m1.m33;
        float t20 = m20 * m1.m00 + m21 * m1.m10 + m22 * m1.m20 + m23 * m1.m30;
        float t21 = m20 * m1.m01 + m21 * m1.m11 + m22 * m1.m21 + m23 * m1.m31;
        float t22 = m20 * m1.m02 + m21 * m1.m12 + m22 * m1.m22 + m23 * m1.m32;
        float t23 = m20 * m1.m03 + m21 * m1.m13 + m22 * m1.m23 + m23 * m1.m33;
        float t30 = m30 * m1.m00 + m31 * m1.m10 + m32 * m1.m20 + m33 * m1.m30;
        float t31 = m30 * m1.m01 + m31 * m1.m11 + m32 * m1.m21 + m33 * m1.m31;
        float t32 = m30 * m1.m02 + m31 * m1.m12 + m32 * m1.m22 + m33 * m1.m32;
        float t33 = m30 * m1.m03 + m31 * m1.m13 + m32 * m1.m23 + m33 * m1.m33;
        m00 = t00; m01 = t01; m02 = t02; m03 = t03;
        m10 = t10; m11 = t11; m12 = t12; m13 = t13;
        m20 = t20; m21 = t21; m22 = t22; m23 = t23;
        m30 = t30; m31 = t31; m32 = t32; m33 = t33;
    }
    
    public final void transform(Vector4f vec) {
        float x = m00 * vec.x + m01 * vec.y + m02 * vec.z + m03 * vec.w;
        float y = m10 * vec.x + m11 * vec.y + m12 * vec.z + m13 * vec.w;
        float z = m20 * vec.x + m21 * vec.y + m22 * vec.z + m23 * vec.w;
        float w = m30 * vec.x + m31 * vec.y + m32 * vec.z + m33 * vec.w;
        vec.x = x;
        vec.y = y;
        vec.z = z;
        vec.w = w;
    }
    
    public final void get(FloatBuffer buffer) {
        buffer.put(m00).put(m01).put(m02).put(m03);
        buffer.put(m10).put(m11).put(m12).put(m13);
        buffer.put(m20).put(m21).put(m22).put(m23);
        buffer.put(m30).put(m31).put(m32).put(m33);
        buffer.flip();
    }
}
